﻿using System;

namespace GenData
{
    public class ProcessBar
    {
        public long total { get; set; }
        public long count { get; set; }

        public ProcessBar(long total, long count)
        {
            this.total = total;
            this.count = count;
        }

        public void updateCount(int counts, string suffix = "")
        {
            lock (this)
            {
                count += counts;
                flushProcess(suffix);
            }
        }

        private void flushProcess(string suffix)
        {
            int w = (int) (Console.WindowWidth * 0.4);
            float p = count * 1f / total;
            int lw = (int) (p * w);
            int rw = w - lw;
            Consoler.writeLine($"\r当前进度，[{new string('#', lw) + new string(' ', rw)}] | {p:#.00%} | {count}/{total} | {suffix}");
        }
    }
    
    public class Consoler
    {
        private static string lastContext = "";//用于记录上次写的内容
        
        private static readonly object @lock = new object();//加锁保证只有一个输出
        
        public static void write(string context)
        {
            lastContext = context;//记录上次写的内容
            lock (@lock)
            {
                Console.Write(context);
            }

        }
        /// <summary>
        /// 覆写
        /// </summary>
        /// <param name="context"></param>
        public static void overWrite(string context = null)
        {
            lastContext = context;//记录上次写的内容
            int strLen = context?.Length ?? 0;
            //空白格的长度，考虑到内容可能超出一行的宽度，所以求余。
            int blankLen = Console.WindowWidth - strLen % Console.WindowWidth - 1;
            int rowCount = strLen / Console.WindowWidth;
            Console.SetCursorPosition(0, Console.CursorTop - rowCount);
            //空白只需填充最后一行的剩余位置即可。
            lock (@lock)
            {
                Console.Write(context + new string(' ', blankLen));
            }
        }

        public static void writeLine(string context = null)
        {
            clearConsoleLine();//清除最后一行
            lock (@lock)
            {
                Console.WriteLine(context);
                if (!string.IsNullOrWhiteSpace(lastContext))
                    Console.Write(lastContext);//重新输出最后一次的内容，否则有较明显的闪烁
                lastContext = null;
            }
        }
        
        public static void clearConsoleLine(int invertedIndex = 0)
        {
            int currentLineCursor = Console.CursorTop;
            int top = Console.CursorTop - invertedIndex;
            top = top < 0 ? 0 : top;
            Console.SetCursorPosition(0, top);
            Console.Write(new string(' ', Console.WindowWidth - 1));
            Console.SetCursorPosition(0, currentLineCursor);
        }
    }

}